AWS SDK for SwiftのGet Startedを試してS3バケットの一覧を取得してみた
こんにちは、AWS事業本部の荒平(@0Air)です。
Swift(iOS)でAWSの各リソースを触ってみたいなと思うことはありませんか?私は年10回くらい思います。
私はSwiftは2.xの頃に少し触れただけのズブの素人なので、今は何もかも変わってしまっていますが、いい感じのGet Startedがあったので試しに触ってみたいと思います。
以下のドキュメントに沿って確認してみます。
はじめに
- 執筆時点で、上記ドキュメントはプレビューリリースです。記載する全ての内容は変更される場合があります
- 実稼働での利用は推奨されていません
- 筆者環境は、
Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
および、aws-sdk-swift v0.36.1
にて試しました - 最小バージョンの要件は
Swift 5.7
およびXcode 14
です。
プロジェクトの作成
ドキュメントに従い、以下コマンドにてプロジェクトを作成します。
mkdir ListBuckets cd ListBuckets swift package init --type executable mv Sources/main.swift Sources/entry.swift
ファイル構成は以下のようになります。
$ tree . ├── Package.swift └── Sources └── entry.swift
Package.swift
およびentry.swift
はgitにて公開されていますので、そちらからコピーしてもよいと思います。(参考)
Package.swift
は以下のように記述しました。
特に15行目は、ご利用の環境に合わせてバージョンを変更してください。
// swift-tools-version: 5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "ListBuckets", platforms: [ .macOS(.v11), .iOS(.v13) ], dependencies: [ .package( url: "https://github.com/awslabs/aws-sdk-swift", from: "0.36.1" ) ], targets: [ .executableTarget( name: "ListBuckets-Simple", dependencies: [ .product(name: "AWSS3", package: "aws-sdk-swift") ], path: "Sources") ] )
entry.swift
は以下の通りです。
9行目region:
は確認したいリージョンに変更します。
// The Swift Programming Language // https://docs.swift.org/swift-book import Foundation import ClientRuntime import AWSS3 func getBucketNames() async throws -> [String] { let client = try S3Client(region: "ap-northeast-1") let output = try await client.listBuckets( input: ListBucketsInput() ) var bucketNames: [String] = [] guard let buckets = output.buckets else { return bucketNames } for bucket in buckets { bucketNames.append(bucket.name ?? "<unknown>") } return bucketNames } @main struct Main { static func main() async { do { let names = try await getBucketNames() print("Found \(names.count) buckets:") for name in names { print(" \(name)") } } catch let error as ServiceError { print("An Amazon S3 service error occurred: \(error.message ?? "No details available")") } catch { print("An unknown error occurred: \(dump(error))") } } }
サンプルコードを実行してみる
それぞれファイルを変更して保存したら、ターミナルからswift build
にてビルドします。
$ swift build Building for debugging... [3/3] Linking ListBuckets-Simple Build complete! (3.46s)
swift run
にてコードを実行できますが、この際、ターミナルの認証情報を利用するため注意が必要です。
~/.aws/credentials
に認証情報をセットしていない場合は、一時的に以下のコマンドで設定します。
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY_ID" export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_ACCESS_KEY"
そして実行すると、しっかりS3バケットの一覧が取得できました。
$swift run Building for debugging... Build complete! (0.25s) 2024-02-24T02:49:54+0900 info S3Client : [Logging] Request: GET https:443 Path: / User-Agent: aws-sdk-swift/1.0 ua/2.0 api/s3#1.0 os/macos#14.2.1 lang/swift#5.9 cfg/retry-mode#legacy, X-Amz-Date: 20240223T174954Z, Host: s3.ap-northeast-1.amazonaws.com, x-amz-content-sha256: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, Authorization: AWS4-HMAC-SHA256 Credential=AKIAXXXXXXXXXXXXXXXX/20240223/ap-northeast-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Optional([ClientRuntime.SDKURLQueryItem(name: "x-id", value: Optional("ListBuckets"))]) 2024-02-24T02:49:55+0900 info URLSessionHTTPClient : [Logging] urlSession(_:dataTask:didReceive:) called 2024-02-24T02:49:55+0900 info URLSessionHTTPClient : [Logging] urlSession(_:dataTask:didReceive:) called with 1936 bytes 2024-02-24T02:49:55+0900 info URLSessionHTTPClient : [Logging] urlSession(_:task:didCompleteWithError:) called. Success Found 15 buckets: amazon-connect-xxxxxxx aws-glue-assets-xxxxxxx-ap-northeast-1 backup-data-arap (省略)
(参考)既存プロジェクトに対して導入する場合
既存のプロジェクトに対してAWS SDK for Swift
パッケージをプロジェクトに追加します。
`https://github.com/awslabs/aws-sdk-swift` を検索欄に入力し、 "Add to Project"にて追加先のプロジェクトを指定、 "Add Package"にてパッケージをインポートします。
AWS SDK for Swiftのインポートが始まります。
少し待機するとサービス一覧が表示されるので、利用するサービス(例えば、AWSS3
)をプロジェクトに追加指定します。
チュートリアルはここまで
・・・なのですが、やはりiOSの画面でも表示させたいなぁと思ったので、作ってみました。
コード例
以下、作成したサンプルコードです。3ファイルに分割しています。
import Foundation import ClientRuntime import AWSS3 import SwiftUI func getBucketNames() async throws -> [String] { let client = try S3Client(region: "ap-northeast-1") let output = try await client.listBuckets( input: ListBucketsInput() ) var bucketNames: [String] = [] guard let buckets = output.buckets else { return bucketNames } for bucket in buckets { bucketNames.append(bucket.name ?? "<unknown>") } return bucketNames } @main struct awssdkforswift: App { var body: some Scene { WindowGroup { BucketListView() } } }
import SwiftUI struct BucketListView: View { @StateObject private var viewModel = BucketListViewModel() var body: some View { NavigationView { List(viewModel.bucketNames, id: \.self) { name in Text(name) } .navigationTitle("S3 Buckets") .onAppear { viewModel.fetchBucketNames() } } } }
import SwiftUI import Combine class BucketListViewModel: ObservableObject { @Published var bucketNames: [String] = [] @Published var isLoading = false @Published var errorMessage: String? func fetchBucketNames() { isLoading = true Task { do { let names = try await getBucketNames() DispatchQueue.main.async { self.bucketNames = names self.isLoading = false } } catch { DispatchQueue.main.async { self.errorMessage = error.localizedDescription self.isLoading = false } } } } }
最後に、適当なXcodeプロジェクトを新規作成し、作成したコードをプロジェクトにAddします。
(デバイスは、特にこだわりはありませんが、iPhone 15 Proを指定しました)
認証情報の設定
iOSで表示させるためには、XcodeにAWS操作用の認証情報を設定してあげる必要があります。
※ ここでは、検証のために環境変数で設定しますが、プロダクションでは非推奨です
Scheme
> Edit Scheme
から、スキーマ操作画面に移動します。
Run
の環境変数を設定します。設定するのは以下の3変数です。
- AWS_REGION
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
S3バケットの一覧が表示できた!
実行してみると、アプリ上からAmazon S3のバケット一覧を取得することができました。
辿り着くまで紆余曲折あったのですが、Xcodeはエラーメッセージが優しい(諸説あり)ので、なんとかなりました。
おわりに
実施内容は基本的ですが、AWS SDK for Swift
を利用すると色々できそうなことが分かりました。
今回は環境変数にアクセスキーを直で入れましたが、本来は別の認証方法を利用すべきなので、要改善です。
2021年終盤に登場し、まだプレビューリリースではありますが、直近でもかなり活発にコミットされていそうなので、幅広く遊べそうです。
このエントリが誰かの助けになれば幸いです。
それでは、AWS事業本部 コンサルティング部の荒平(@0Air)がお送りしました!